package com.duobaoyu.dby.supply.biz.client.resource.bean.dto;

import cn.hutool.core.collection.CollectionUtil;
import com.duobaoyu.dby.channel.adapter.enums.biz.refund.AfterSaleTypeEnum;
import com.duobaoyu.dby.saas.product.common.base.enums.RepositoryTypeEnum;
import com.duobaoyu.dby.saas.product.common.base.serializer.BigDecimalSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.URL;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName ChannelSettingConfigDTO
 * @createTime 14:50:00 2023/08/25
 */
@Data
public class ChannelSetConfigDTO implements Serializable {
    private static final long serialVersionUID = -8958968012615562428L;

    /**
     * 渠道配置ID
     */
    @NotNull(message = "渠道配置ID不能为空")
    @ApiModelProperty(value = "渠道配置ID")
    private Long id;
    /**
     * 渠道编码
     */
    @NotBlank(message = "渠道编码不能为空")
    @ApiModelProperty(value = "渠道编码")
    private String channelCode;
    /**
     * 配置类型 1->预估运费配置；2->售后配置；3->审核策略配置；4->订单规则配置
     * //@see ChannelSettingTypeEnum
     */
    @NotNull(message = "配置类型不能为空")
    @ApiModelProperty(value = "配置类型 1->预估运费配置；2->售后配置；3->审核策略配置；4->订单规则配置")
    private Integer configType;
    /**
     * 配置参数-JSON
     */
    @NotNull(message = "配置参数不能为空")
    @ApiModelProperty(value = "配置参数-JSON")
    private ParamConfig ifParam;

    @Data
    public static class ParamConfig {
        /**
         * 售后配置
         */
        @Valid
        @NotEmpty(message = "售后配置不能为空",groups = {AfterSaleConfigGroup.class})
        @ApiModelProperty(value = "售后配置")
        private List<AfterSaleConfig> afterSaleConfigs;
        /**
         * 审核策略配置
         */
        @Valid
        @NotNull(message = "审核策略不能为空",groups = {AuditStrategyGroup.class})
        @ApiModelProperty(value = "审核策略")
        private AuditStrategy auditStrategy;
        /**
         * 预估运费配置
         */
        @Valid
        @NotNull(message = "预估运费配置不能为空",groups = {PreFreightGroup.class})
        @ApiModelProperty(value = "预估运费配置")
        private Prefreight prefreight;
        /**
         * 订单规则配置
         */
        @Valid
        @NotNull(message = "订单规则配置不能为空",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "订单规则配置")
        private OrderRule orderRule;
        /**
         * 预估运费设置
         */
        @Data
        public static class Prefreight {

            /**
             * 运费条件1:订单金额
             */
            @NotNull(message = "运费条件不能为空",groups = {PreFreightGroup.class})
            @ApiModelProperty(value = "运费条件 1:订单金额")
            private Integer freightFilter;
            /**
             * 运费配置json
             */
            @Valid
            @NotEmpty(message = "运费参数不能为空",groups = {PreFreightGroup.class})
            @ApiModelProperty(value = "运费参数")
            private List<PrefreightParam> freightParam;
            /**
             * 计费方式: 1:区间计费
             */
            @NotNull(message = "计费方式不能为空",groups = {PreFreightGroup.class})
            @ApiModelProperty(value = "计费方式 1:区间计费")
            private Integer freightWay;

            @Data
            public static class PrefreightParam {
                /**
                 * 开始金额
                 **/
                @NotNull(message = "起始金额不能我空",groups = {PreFreightGroup.class})
                @Min(message = "起始金额设置有误",groups = {PreFreightGroup.class},value = 0)
                @JsonSerialize(using = BigDecimalSerializer.class)
                @ApiModelProperty(value = "起始金额")
                private BigDecimal startValue;
                /**
                 * 结束金额
                 */
                @Min(message = "结束金额设置有误",groups = {PreFreightGroup.class},value = 0)
                @JsonSerialize(using = BigDecimalSerializer.class)
                @ApiModelProperty(value = "结束金额")
                private BigDecimal endValue;
                /**
                 * 预估运费
                 */
                @NotNull(message = "预估运费不能为空",groups = {PreFreightGroup.class})
                @Min(message = "预估运费设置有误",groups = {PreFreightGroup.class},value = 0)
                @JsonSerialize(using = BigDecimalSerializer.class)
                @ApiModelProperty(value = "预估运费")
                private BigDecimal freightValue;

                /**
                 * 排序
                 */
                @NotNull(message = "排序不能为空",groups = {PreFreightGroup.class})
                @ApiModelProperty(value = "排序")
                private Integer isSort;
            }
        }
        /**
         * 审核策略
         */
        @Data
        public static class AuditStrategy {
            /**
             * 自动审核开关 true - 开启 ； false - 关闭
             */
            @NotNull(message = "自动审核开关不能为空",groups = {AuditStrategyGroup.class})
            @ApiModelProperty(value = "自动审核开关 true - 开启 ； false - 关闭")
            private Boolean enable;
            /**
             * 自动提交审核时间（单位：小时）
             */
            @NotNull(message = "自动提交审核时间不能为空",groups = {AuditStrategyGroup.class})
            @Min(message = "预自动提交审核时间设置有误",groups = {AuditStrategyGroup.class},value = 0)
            @ApiModelProperty(value = "自动提交审核时间（单位：小时）")
            private Integer autoSubmit;
        }

        /**
         * 售后配置
         */
        @Data
        public static class AfterSaleConfig {
            /**
             * 配置名称
             */
            @ApiModelProperty(value = "配置名称")
            private String configName;
            /**
             * 仓库类型
             * @see RepositoryTypeEnum
             */
            @ApiModelProperty(value = "仓库类型")
            private List<Integer> repositoryTypes;
            /**
             * 售后类型 1:退货退款 2:换货 3:维修 4-仅退款
             * @see AfterSaleTypeEnum
             */
            @ApiModelProperty(value = "售后类型")
            private List<Integer> afterSaleTypes;
            /**
             * 售后规则
             */
            @ApiModelProperty(value = "售后规则")
            private List<AfterSaleRule> afterSaleRules;
            @ApiModelProperty(value = "售后规则,适配前端结构")
            private Map<Integer, List<Integer>> afterSaleRuleObj;
            /**
             * 售后说明（图片URL）
             */
            @URL(message = "售后说明格式错误",groups = {AfterSaleConfigGroup.class})
            @NotBlank(message = "售后说明不能为空",groups = {AfterSaleConfigGroup.class})
            @ApiModelProperty(value = "售后说明（图片URL）")
            private String explainUrl;
            @Data
            public static class AfterSaleRule{
                /**
                 * 售后类型 1:退货退款 2:换货 3:维修 4-仅退款
                 * @see AfterSaleTypeEnum
                 */
                @ApiModelProperty(value = "售后类型")
                private Integer afterSaleType;
                /**
                 * 支持的订单状态 10-待支付;20-处理中;21-处理失败;30-待发货;40-部分发货;41-已发货;50-部分成功;60-已完成;70-取消中;71-已取消;
                 * @see
                 */
                @ApiModelProperty(value = "支持的订单状态")
                private List<Integer> orderStatus;
            }
            public List<AfterSaleRule> getAfterSaleRules() {
                if (CollectionUtil.isNotEmpty(this.afterSaleRules)) {
                    return this.afterSaleRules;
                }
                return Optional.ofNullable(this.getAfterSaleRuleObj()).orElse(Maps.newHashMap()).entrySet().stream().map(obj -> {
                    AfterSaleRule rule = new AfterSaleRule();
                    rule.setAfterSaleType(obj.getKey());
                    rule.setOrderStatus(obj.getValue());
                    return rule;
                }).collect(Collectors.toList());
            }

            public List<Integer> getAfterSaleTypes() {
                if (CollectionUtil.isNotEmpty(this.afterSaleTypes)) {
                    return this.afterSaleTypes;
                }
                return Lists.newArrayList(Optional.ofNullable(this.getAfterSaleRuleObj()).orElse(Maps.newHashMap()).keySet());
            }
        }
    }

    @Data
    public static class OrderRule {
        /**
         * 商品拆单种类个数
         */
        @Min(message = "商品拆单种类个数设置有误",value = 1,groups = {OrderRuleGroup.class})
        @NotNull(message = "商品拆单种类个数未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "商品拆单种类个数")
        private Integer skuSplitVarietyCount;
        /**
         * 用户下单未付款，自动取消时间（单位：天）
         */
        @Max(message = "订单自动消息时间（天）设置有误",value = 7,groups = {OrderRuleGroup.class})
        @Min(message = "订单自动消息时间（天）设置有误",value = 0,groups = {OrderRuleGroup.class})
        @NotNull(message = "订单自动消息时间（天）未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "用户下单未付款，自动取消时间（单位：天）")
        private Integer orderCancelDay;
        /**
         * 用户下单未付款，自动取消时间（单位：小时）
         */
        @Max(message = "订单自动消息时间（小时）设置有误",value = 23,groups = {OrderRuleGroup.class})
        @Min(message = "订单自动消息时间（小时）设置有误",value = 0,groups = {OrderRuleGroup.class})
        @NotNull(message = "订单自动消息时间（小时）未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "用户下单未付款，自动取消时间（单位：小时）")
        private Integer orderCancelHour;
        /**
         * 用户下单未付款，自动取消时间（单位：分钟）
         */
        @Max(message = "订单自动消息时间（分钟）设置有误",value = 59,groups = {OrderRuleGroup.class})
        @Min(message = "订单自动消息时间（分钟）设置有误",value = 30,groups = {OrderRuleGroup.class})
        @NotNull(message = "订单自动消息时间（分钟）未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "用户下单未付款，自动取消时间（单位：分钟）")
        private Integer orderCancelMinute;
        /**
         * 发货订单自动确认收货时间（单位：天）
         */
        @Max(message = "发货订单自动确认收货时间（天）设置有误",value = 15,groups = {OrderRuleGroup.class})
        @Min(message = "发货订单自动确认收货时间（天）设置有误",value = 7,groups = {OrderRuleGroup.class})
        @NotNull(message = "发货订单自动确认收货时间未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "发货订单自动确认收货时间（单位：天）")
        private Integer shippingOrderConfirmTime;
        /**
         * 订单确认后，不能申请售后时间（单位：天）
         */
        @Max(message = "订单确认后，不能申请售后时间（天）设置有误",value = 15,groups = {OrderRuleGroup.class})
        @Min(message = "订单确认后，不能申请售后时间（天）设置有误",value = 7,groups = {OrderRuleGroup.class})
        @NotNull(message = "发订单确认后，不能申请售后时间未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "订单确认后，不能申请售后时间（单位：天）")
        private Integer orderConfirmNotAfterSaleTime;
        /**
         * 退换货/维修售后审核通过后，用户多长时间未寄回商品，自动取消售后（单位：天）
         */
        @Max(message = "退换货/维修售后审核通过后，用户多长时间未寄回商品，自动取消售后（天）设置有误",value = 7,groups = {OrderRuleGroup.class})
        @Min(message = "退换货/维修售后审核通过后，用户多长时间未寄回商品，自动取消售后（天）设置有误",value = 3,groups = {OrderRuleGroup.class})
        @NotNull(message = "退换货/维修售后审核通过后，用户多长时间未寄回商品，自动取消售后时间未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "退换货/维修售后审核通过后，用户多长时间未寄回商品，自动取消售后（单位：天）")
        private Integer returnProductRefundCancelTime;
        /**
         * 售后完成，自动确认售后完成时间（单位： 天）
         */
        @Max(message = "自动确认售后完成时间（天）设置有误",value = 7,groups = {OrderRuleGroup.class})
        @Min(message = "自动确认售后完成时间（天）设置有误",value = 3,groups = {OrderRuleGroup.class})
        @NotNull(message = "自动确认售后完成时间未设置",groups = {OrderRuleGroup.class})
        @ApiModelProperty(value = "售后完成，自动确认售后完成时间（单位： 天）")
        private Integer autoAfteSaleCompleteTime;
    }

    public interface AfterSaleConfigGroup{}
    public interface AuditStrategyGroup{}
    public interface PreFreightGroup{}
    public interface OrderRuleGroup{}
}
